home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Various / DevDisk 65 (1989)(DevWare PD).zip / DevDisk 65 (1989)(DevWare PD).adf / prosuite / filename.c < prev    next >
C/C++ Source or Header  |  1990-07-11  |  10KB  |  384 lines

  1.  
  2. /* *** filename.c ***********************************************************
  3.  *
  4.  * File IO Suite  --  File Name Construction Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
  15.  * All copyright notices and all file headers must be retained intact.
  16.  * The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the 
  17.  * resultant object code may be included in any software product.  However, no 
  18.  * portion of the source listings or documentation of the Amiga Programmer's 
  19.  * Suite Book 1 may be distributed or sold for profit or in a for-profit 
  20.  * product without the written authorization of the author, RJ Mical.
  21.  * 
  22.  * HISTORY      NAME            DESCRIPTION
  23.  * -----------  --------------  --------------------------------------------
  24.  * 4 Feb 87     RJ              Real release
  25.  * 12 Aug 86    RJ >:-{)*       Prepare (clean house) for release
  26.  * 3 May 86     =RJ Mical=      Fix prop gadget for both 1.1 and 1.2
  27.  * 1 Feb 86     =RJ Mical=      Created this file.
  28.  *
  29.  * *********************************************************************** */
  30.  
  31.  
  32. #define FILEIO_SOURCEFILE
  33. #include "fileio.h"
  34. #include <libraries/dosextens.h>
  35.  
  36.  
  37. #define FRIENDLY_NOT        0
  38. #define FRIENDLY_DRAWER        1
  39. #define FRIENDLY_OTHER        2
  40.  
  41.  
  42.  
  43. VOID BuildNameTable(fileio)
  44. struct FileIOSupport *fileio;
  45. /* This routine searches through the fileio lock for all file entries,
  46.  * and builds a list of the names found.
  47.  * If the user wants Workbench-style pattern matching, filenames are
  48.  * passed through a filter before being added to the list.
  49.  * All directory entries are added to the list.
  50.  */
  51. {
  52.     struct FileInfoBlock *fileinfo;
  53.     UBYTE *ptr;
  54.     UBYTE workname[MAX_NAME_LENGTH + 5]; /* the extra 5 are for the ".info" */
  55.     struct Remember **key;
  56.     ULONG lock;
  57.     SHORT i, flags, type;
  58.     SHORT pick;
  59.  
  60.     fileio->NameCount = 0;
  61.     lock = fileio->DOSLock;
  62.     key = &fileio->NameKey;
  63.     FreeRemember(key, TRUE);
  64.     ClearFlag(fileio->Flags, GOOD_FILENAMES);
  65.  
  66.     if ((fileinfo = (struct FileInfoBlock *)AllocMem(
  67.             sizeof(struct FileInfoBlock), MEMF_CLEAR)) == NULL)
  68.         goto BUILD_EXIT;
  69.  
  70.     SetWaitPointer(OpenReqWindow);
  71.  
  72.     /* Now, first, before we might be interrupted by MessageInterrupt(),
  73.      * check whether or not we're looking in a drawer and, if so, add the
  74.      * entry that allows the user to ascend one drawer.
  75.      */
  76.     if (StringLength(&OpenReqFileIO->DrawerName[0]))
  77.         {
  78.         MakeEntry("\253\253 PRIOR DRAWER", key, NAMED_PREVIOUS);
  79.         /* bump the master count */
  80.         fileio->NameCount++;
  81.         }
  82.  
  83.     /* starting from Examine() until ExNext() is NULL */
  84.     if (Examine(lock, fileinfo))
  85.         while (ExNext(lock, fileinfo))
  86.             {
  87.             /* Default:  this entry is a normal file */
  88.             flags = NULL;
  89.             CopyString(&workname[0], fileinfo->fib_FileName);
  90.  
  91. #ifdef WBENCH_CODE
  92.             /* Now, does the caller want Workbench-style pattern matching? */
  93.             if (FlagIsSet(fileio->Flags, WBENCH_MATCH))
  94.                 {
  95.                 /* start from location 1 to avoid matching the ".info" file */
  96.                 if (ptr = FindSuffix(&workname[1], ".info")) 
  97.                     {
  98.                     *ptr = '\0';    /* strip the suffix off that baby */
  99.  
  100.                     /* Get the friendliness quotient of this .info file */
  101.                     type = FriendlyInfoType(&workname[0], fileio);
  102.  
  103.                     /* If just not friendly, forget about it */
  104.                     if (type == FRIENDLY_NOT) goto NEXT_LOCK;
  105.  
  106.                     /* If this was a drawer, set the fileinfo as a directory */
  107.                     if (type == FRIENDLY_DRAWER)
  108.                         fileinfo->fib_DirEntryType = 1;
  109.                     }
  110.                 else goto NEXT_LOCK;
  111.                 }
  112. #endif /* ... of WBENCH_CODE conditional */
  113.  
  114.             if (fileinfo->fib_DirEntryType >= 0)
  115.                 {
  116.                 /* This entry is a directory */
  117.                 flags = NAMED_DIRECTORY;
  118.  
  119.                 /* If you change the following text, change DIR_TEXT_SIZE too */
  120.                 for (i = StringLength(&workname[0]); i >= 0; i--)
  121.                     workname[i + DIR_TEXT_SIZE] = workname[i];
  122.                 workname[0] = '\273';
  123.                 workname[1] = '\273';
  124.                 workname[2] = ' ';
  125.                 }
  126.  
  127.             pick = MakeEntry(&workname[0], key, flags);
  128.             /* bump the master count */
  129.             fileio->NameCount++;
  130.  
  131.             if (pick <= fileio->CurrentPick)
  132.                 fileio->CurrentPick++;
  133.  
  134.             InitOpenProp(FALSE);
  135.             StuffSelectNames(2);
  136.  
  137. NEXT_LOCK:
  138.             /* If there's a message pending, split with what we've got */
  139.             if (MessageInterrupt()) goto EXAMINE_DONE;
  140.             }
  141.  
  142.     SetFlag(fileio->Flags, GOOD_FILENAMES);
  143.  
  144.  
  145. EXAMINE_DONE:
  146.  
  147.     if (OpenReqWindow) ClearPointer(OpenReqWindow);
  148.     FreeMem(fileinfo, sizeof(struct FileInfoBlock));
  149.  
  150.  
  151. BUILD_EXIT: ;
  152. }
  153.  
  154.  
  155.  
  156. VOID PropInterrupt()
  157. /* This routine is called by MessageInterrupt() if the prop gadget 
  158.  * is played with while the file name table is being built.  
  159.  * As long as the user is using the proportional gadget, hang around here. 
  160.  */
  161. {
  162.     struct IntuiMessage *message;
  163.     struct Gadget *gadget;
  164.     BOOL mousemove;
  165.  
  166.     FOREVER
  167.         {
  168.         WaitPort(OpenReqWindow->UserPort);
  169.         mousemove = FALSE;
  170.  
  171.         while (message = GetMsg(OpenReqWindow->UserPort))
  172.             {
  173.             switch (message->Class)
  174.                 {
  175.                 case GADGETUP:
  176.                     gadget = (struct Gadget *)message->IAddress;
  177.                     switch (gadget->GadgetID)
  178.                         {
  179.                         case OPENGADGET_PROPGADGET:
  180.                             ReplyMsg(message);
  181.                             HandleGadget(gadget, 0, 0, 0, 0);
  182.                             return;
  183.  
  184.                         default:
  185.                             goto MESSAGE_RETURN;
  186.                         }
  187.                     break;
  188.  
  189.                 case MOUSEMOVE:
  190.                     ReplyMsg(message);
  191.                     mousemove = TRUE;
  192.                     break;
  193.  
  194.                 default:
  195.                     goto MESSAGE_RETURN;
  196.  
  197.                 }
  198.             }
  199.  
  200.         if (mousemove) PropMouseMoves();
  201.         }
  202.  
  203. MESSAGE_RETURN:
  204.     /* Pretend we didn't see this message */
  205.     AddHead(&OpenReqWindow->UserPort->mp_MsgList, message);
  206. }
  207.  
  208.  
  209.  
  210. BOOL MessageInterruptGrunt(message)
  211. struct IntuiMessage *message;
  212. /* Test if there's a gadget type of message at the window port, 
  213.  * react to it if there is one, and return TRUE if the message is 
  214.  * one that should interrupt the building of the file name list.
  215.  */
  216. {
  217.     ULONG class;
  218.     SHORT x, y;
  219.     struct Gadget *gadget;
  220.     LONG seconds, micros;
  221.  
  222.     class = message->Class;
  223.     if ((class == GADGETDOWN) || (class == GADGETUP))
  224.         {
  225.         gadget = (struct Gadget *)message->IAddress;
  226.         x = message->MouseX;
  227.         y = message->MouseY;
  228.         seconds = message->Seconds;
  229.         micros = message->Micros;
  230.         OpenReqSupport.SelectedGadgetID = gadget->GadgetID;
  231.  
  232.         switch (gadget->GadgetID)
  233.             {
  234.             case OPENGADGET_SELECTNAME:
  235.                 y = HandleSelect(y, seconds, micros);
  236.                 if ((y == -1) || (y == 1))
  237.                     {
  238.                     /* Pretend we didn't see this message */
  239.                     AddHead(&OpenReqWindow->UserPort->mp_MsgList, message);
  240.                     return(TRUE);
  241.                     }
  242.  
  243.                 StuffFileName();
  244.                 StuffSelectNames(5);
  245.                 goto REPLY_AND_RETURN_FALSE;
  246.  
  247.             case OPENGADGET_UPGADGET:
  248.             case OPENGADGET_DOWNGADGET:
  249.                 goto REPLY_AND_RETURN_FALSE;
  250.  
  251.             case OPENGADGET_PROPGADGET:
  252.                 HandleGadget(gadget, x, y, seconds, micros);
  253.                 if (class == GADGETDOWN) PropInterrupt();
  254.                 goto REPLY_AND_RETURN_FALSE;
  255.  
  256.             default:
  257.                 /* Do nothing, fall into the message's AddHead() below.
  258.                  * This includes the gadgets OK, CANCEL, NEXTDISK, 
  259.                  * DISKNAME, DRAWERNAME, FILENAME, and BACKDROP.
  260.                  */
  261.                 break;
  262.             }
  263.         }
  264.  
  265.     /* Pretend we didn't see this message */
  266.     AddHead(&OpenReqWindow->UserPort->mp_MsgList, message);
  267.     return(TRUE);
  268.  
  269. REPLY_AND_RETURN_FALSE:
  270.     ReplyMsg(message);
  271.     return(FALSE);
  272. }
  273.  
  274.  
  275.  
  276. BOOL MessageInterrupt()
  277. /* Call MessageInterruptGrunt() with each message.
  278.  * Return TRUE if the message is one that should interrupt the building 
  279.  * of the file name list, else return FALSE.
  280.  */
  281. {
  282.     struct IntuiMessage *message;
  283.  
  284.     while (message = GetMsg(OpenReqWindow->UserPort))
  285.         {
  286.         if (MessageInterruptGrunt(message))
  287.             return(TRUE);
  288.         }
  289.     return(FALSE);
  290. }
  291.  
  292.  
  293.  
  294. SHORT MakeEntry(name, startkey, flags)
  295. UBYTE *name;
  296. struct Remember **startkey;
  297. UBYTE flags;
  298. {
  299.     SHORT length, pos;
  300.     struct Remember *localkey, *nextkey, *oldkey;
  301.     UBYTE *ptr;
  302.  
  303.     /* length equals the length of the text plus one for the 
  304.      * terminating NULL
  305.      */
  306.     length = StringLength(name) + 1;
  307.     localkey = NULL;
  308.     /* Alloc one larger than length to make room for the flag byte */
  309.     ptr = AllocRemember(&localkey, length + 1, NULL);
  310.     if (ptr == NULL) return(32767);
  311.     CopyString(ptr, name);
  312.     *(ptr + length) = flags;
  313.     nextkey = *startkey;
  314.     pos = 0;
  315.     oldkey = NULL;
  316.     while (nextkey)
  317.         {
  318.         if (CompareUpperStrings(nextkey->Memory, name) >= 0)
  319.             goto DONE;
  320.  
  321.         oldkey = nextkey;
  322.         nextkey = nextkey->NextRemember;
  323.         pos++;
  324.         }
  325.  
  326. DONE:
  327.     if (oldkey) oldkey->NextRemember = localkey;
  328.     else *startkey = localkey;
  329.     localkey->NextRemember = nextkey;
  330.     return(pos);
  331. }
  332.  
  333.  
  334.  
  335.  
  336. #ifdef WBENCH_CODE
  337.  
  338. SHORT FriendlyInfoType(infoname, fileio)
  339. UBYTE *infoname;
  340. struct FileIOSupport *fileio;
  341. /* This routine looks at the .info file that's named infoname and
  342.  * tests to see if its object type and tool type match the specifications
  343.  * in the fileio structure.  Returns TRUE if everything matches.
  344.  * If the .info file couldn't be opened or if the requirements don't
  345.  * match, FALSE is returned.
  346.  */
  347. {
  348.     struct DiskObject *object;
  349.     SHORT result;
  350.  
  351.     result = FRIENDLY_NOT;
  352.     if (object = GetDiskObject(infoname)) 
  353.         {
  354.         if ((object->do_Type == WBDRAWER) || (object->do_Type == WBGARBAGE))
  355.             result = FRIENDLY_DRAWER;
  356.         else if (object->do_Type == WBDISK) 
  357.             result = FRIENDLY_NOT;
  358.         else
  359.             {
  360.             if (FlagIsSet(fileio->Flags, MATCH_OBJECTTYPE))
  361.                 if (object->do_Type != fileio->DiskObjectType) goto FRIEND_DONE;
  362.  
  363.             result = FRIENDLY_OTHER;
  364.  
  365.             if (FlagIsSet(fileio->Flags, MATCH_TOOLTYPE))
  366.                 {
  367.                 if (NOT MatchToolValue(
  368.                        FindToolType(object->do_ToolTypes, "FILETYPE"), 
  369.                         &fileio->ToolType[0]))
  370.                     result = FRIENDLY_NOT;
  371.                 }
  372.             }
  373.         }
  374.  
  375. FRIEND_DONE:
  376.     if (object) FreeDiskObject(object);
  377.     return(result);
  378. }
  379.  
  380. #endif /* ... of WBENCH_CODE conditional */
  381.  
  382.  
  383.  
  384.